package com.gnerv.sylvanas.framework.core.autoconfigure;

import com.gnerv.sylvanas.framework.core.BaseAccountPassword;
import com.gnerv.sylvanas.framework.core.BaseCurrentAccount;
import com.gnerv.sylvanas.framework.core.BaseUkIdGenerate;
import com.gnerv.sylvanas.framework.core.interceptor.MethodExecutionTimeInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Gnerv LiGen
 */
@Slf4j
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(value = {FrameworkCoreConfigProperties.class})
public class FrameworkCoreAutoConfiguration {

    @Bean
    public Advisor restControllerMethodExecutionTimeInterceptor() {
        AnnotationMatchingPointcut annotationMatchingPointcut = new AnnotationMatchingPointcut(RestController.class, true);
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setAdvice(new MethodExecutionTimeInterceptor());
        advisor.setPointcut(annotationMatchingPointcut);
        return advisor;
    }

    @Bean
    public Advisor serviceMethodExecutionTimeInterceptor() {
        AnnotationMatchingPointcut annotationMatchingPointcut = new AnnotationMatchingPointcut(Service.class, true);
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setAdvice(new MethodExecutionTimeInterceptor());
        advisor.setPointcut(annotationMatchingPointcut);
        return advisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public BaseAccountPassword baseAccountPassword() {
        return new BaseAccountPassword() {};
    }

    @Bean
    @ConditionalOnMissingBean
    public BaseCurrentAccount baseCurrentAccount() {
        return new BaseCurrentAccount() {};
    }

    @Bean
    @ConditionalOnMissingBean
    public BaseUkIdGenerate baseUkIdGenerate() {
        return new BaseUkIdGenerate() {};
    }
}
